from datetime import datetime

from playwright.sync_api import sync_playwright
from PyQt5.QtCore import QThread, pyqtSignal

from Util.QwDbManager import QwDbManager
from Util.zconfig import get_setting


class WorkerThreadQw(QThread):
    '''
    企业微信审批获取数据类
    '''
    # 线程信号
    upQwLog = pyqtSignal(str)  # 用于更新日志的信号
    qwFinished = pyqtSignal()  # 结束信号
    status_signal = pyqtSignal(str)  # 状态栏信息

    save_download_status_signal = pyqtSignal(dict)# 保存下载状态信号
    save_task_info_signal = pyqtSignal(list)# 保存待审批任务信号

    def __init__(self,datas:list):
        super().__init__()
        self.datas = datas
        self.Debug = get_setting('DEBUG')
        self.min_wait = 1000 #秒
        self.max_wait = 3000

    def run(self):
        page = None
        playwright = None
        browser = None
        try:
            playwright = sync_playwright().start()
        except BaseException as e:
            self.upQwLog('自动化实例创建失败:' + str(e))
            self.finished.emit()
        try:
            browser = playwright.chromium.connect_over_cdp(get_setting('CDPURL'))
            context = browser.contexts[0]
            page = context.pages[0]
            qw_url = get_setting('TASK_URL')['QWTASKURL']
            page.goto(qw_url)
            page.wait_for_load_state()
        except BaseException as e:
            self.upQwLog('连接浏览器失败,请检查谷歌浏览器状态:' + str(e))
            self.finished.emit()
        try:
            person_count = len(self.datas)
            for r, (raw_name, date, run_time, cnt, flag) in enumerate(self.datas):
                name = str(raw_name).strip()
                all_tasks = []  # 1. 收集该人员全部任务
                page_num = 1
                self.status_signal.emit(f"进度:{r+1}/{person_count},正在获取【{name}】数据...")
                try:
                    # 检查是否有“重新选择”出现，最长 3 秒
                    re_select = page.locator('text="重新选择"')
                    if re_select.count():
                        re_select.click(timeout=self.max_wait)
                    else:
                        page.wait_for_timeout(self.max_wait)
                        choose_btn = page.locator('span.choose:has-text("选择需交接成员")')
                        if choose_btn.count():
                            choose_btn.click(timeout=self.max_wait)
                    try:
                        search_input = page.locator('#memberSearchInput')
                        search_input.wait_for(state='visible')

                        # 点击搜索框（确保聚焦）
                        search_input.click(timeout=self.max_wait)

                        # 模拟人工输入 name，并回车
                        search_input.type(name, delay=100)
                        page.wait_for_timeout(self.max_wait)
                        search_input.press('Enter')

                        # 等待确认按钮可点击并点击
                        submit_btn = page.locator('#footer_submit_btn')
                        submit_btn.wait_for(state='visible')
                        submit_btn.click(timeout=self.max_wait)
                    except:
                        raise ValueError('终止步骤: 未找到搜索框或确认按钮')

                    page.wait_for_timeout(self.max_wait)
                    # 检测“暂无数据”
                    empty_loc = page.locator('div.list-empty:has-text("暂无数据")')
                    if empty_loc.count():
                        self.save_download_status_signal.emit({'user_name':name,'task_count':0})
                        continue
                    else:
                        while True:
                            try:
                                page.wait_for_selector('tbody.wwui_table__body > tr', timeout=10_000)
                            except Exception:
                                # 空白页
                                break

                            # 2. 解析当前页
                            rows = page.locator('tbody.wwui_table__body > tr').all()
                            for row in rows:
                                tds = row.locator('td').all()
                                if len(tds) < 3:
                                    continue
                                task_name = (tds[-3].locator('[title]').first.get_attribute('title') or '').strip()
                                task_id = (tds[-2].locator('[title]').first.get_attribute('title') or '').strip()
                                add_time = (tds[-1].locator('[title]').first.get_attribute('title') or '').strip()

                                try:
                                    add_time = datetime.strptime(add_time, '%Y/%m/%d %H:%M').strftime('%Y-%m-%d %H:%M:%S')
                                except ValueError:
                                    add_time = None

                                all_tasks.append({
                                    'user_name': name,
                                    'task_id': task_id,
                                    'task_name': task_name,
                                    'task_add_time': add_time,
                                    'task_get_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                                })

                            # 3. 翻页
                            next_btn = page.locator('.t-pagination__btn-next')
                            if next_btn.count() and 'disabled' not in (next_btn.get_attribute('class') or ''):
                                next_btn.click(timeout=self.max_wait)
                                page.wait_for_load_state('networkidle')
                                page_num += 1
                            else:
                                break  # 最后一页

                        # 4. 人员维度一次性写库
                        if all_tasks:
                            self.save_task_info_signal.emit(all_tasks)
                            self.save_download_status_signal.emit({'user_name': name,'task_count': len(all_tasks)})
                except Exception as e:
                    msg = '人员【' + name + '】数据下载失败:' + str(e)
                    self.upQwLog('已点击“重新选择”')
        except BaseException as e:
            self.upQwLog('任务执行失败:' + str(e))
        finally:
            if page:
                page.close()
            if 'browser' in locals():
                browser.close()
            if 'playwright' in locals():
                playwright.stop()
            self.status_signal.emit("本次下载任务结束")
            self.finished.emit()